﻿using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace FastMapper.Helpers
{
    public static class ExpressionExtensions
    {
        public static MemberExpression GetMemberExpression(this Expression expression)
        {
            dynamic param = null;
            if (expression.NodeType == ExpressionType.Lambda)
            {
                var lambdaExpression = expression as LambdaExpression;
                if (lambdaExpression != null) param = lambdaExpression.Body;
            }
            else if (expression.NodeType == ExpressionType.MemberAccess)
            {
                param = expression;
            }
            else
            {
                return null;
            }
            MemberExpression memberExpression;
            if (param is UnaryExpression)
            {
                var unaryExpression = (UnaryExpression)param.Body;
                memberExpression = (MemberExpression)unaryExpression.Operand;
            }
            else
            {
                memberExpression = (MemberExpression)param;
            }
            return memberExpression;
        }

        public static MemberInfoNode GetMemberInfo(this Expression expression)
        {
            var memberExpression = expression.GetMemberExpression();
            MemberInfoNode result = null;
            if (memberExpression != null)
            {
                result = new MemberInfoNode();
                result.Name = memberExpression.Member.Name;
                result.MemberType = memberExpression.Member.ReflectedType;
                if (memberExpression.Expression != null)
                {
                    var parent = memberExpression.Expression.GetMemberInfo();
                    if (parent != null)
                        result.AddParent(parent);
                }
            }
            return result;
        }

        public static MemberInfoNode GetMemberInfoFromRoot(this Expression expression)
        {
            var memberInfo = expression.GetMemberInfo();
            return memberInfo != null ? memberInfo.GetRootMemberInfoNode() : null;
        }

        public static string GetMemberName(this Expression expression)
        {
            var lambda = (LambdaExpression)expression;

            MemberExpression memberExpression;
            if (lambda.Body is UnaryExpression)
            {
                var unaryExpression = (UnaryExpression)lambda.Body;
                memberExpression = (MemberExpression)unaryExpression.Operand;
            }
            else
            {
                memberExpression = (MemberExpression)lambda.Body;
            }
            return memberExpression.Member.Name;
        }



    }
}
